SuperStrict

rem
	bbdoc: Type description
end rem

Import "../base/ScintillaAbstractDriver.bmx"

'#region Imports
Import brl.System
Import maxgui.win32maxguiex

Import "-lcomctl32"
Import "-lole32"
Import "-loleaut32"
Import "-luuid"
Import "-lmsimg32"
Import "libimm32.a"

Import "..\src\include/*.h"
Import "..\src\src/*.h"
Import "..\src\lexlib/*.h"

Import "..\src\win32\ScintillaWin.cxx"
Import "..\src\win32\PlatWin.cxx"

Import "..\src\src/AutoComplete.cxx"
Import "..\src\src/CallTip.cxx"
Import "..\src\src/Catalogue.cxx"
Import "..\src\src/CellBuffer.cxx"
Import "..\src\src/CharClassify.cxx"
Import "..\src\src/ContractionState.cxx"
Import "..\src\src/Decoration.cxx"
Import "..\src\src/Document.cxx"
Import "..\src\src/Editor.cxx"
Import "..\src\src/ExternalLexer.cxx"
Import "..\src\src/Indicator.cxx"
Import "..\src\src/KeyMap.cxx"
Import "..\src\src/LineMarker.cxx"
Import "..\src\src/PerLine.cxx"
Import "..\src\src/PositionCache.cxx"
Import "..\src\src/RESearch.cxx"
Import "..\src\src/RunStyles.cxx"
Import "..\src\src/ScintillaBase.cxx"
Import "..\src\src/Selection.cxx"
Import "..\src\src/Style.cxx"
Import "..\src\src/UniConversion.cxx"
Import "..\src\src/ViewStyle.cxx"
Import "..\src\src/XPM.cxx"

Import "..\src\lexlib/Accessor.cxx"
Import "..\src\lexlib/CharacterSet.cxx"
Import "..\src\lexlib/LexerBase.cxx"
Import "..\src\lexlib/LexerModule.cxx"
Import "..\src\lexlib/LexerNoExceptions.cxx"
Import "..\src\lexlib/LexerSimple.cxx"
Import "..\src\lexlib/PropSetSimple.cxx"
Import "..\src\lexlib/StyleContext.cxx"
Import "..\src\lexlib/WordList.cxx"

Import "..\src\lexers/LexA68k.cxx"
Import "..\src\lexers/LexAbaqus.cxx"
Import "..\src\lexers/LexAda.cxx"
Import "..\src\lexers/LexAPDL.cxx"
Import "..\src\lexers/LexAsm.cxx"
Import "..\src\lexers/LexAsn1.cxx"
Import "..\src\lexers/LexASY.cxx"
Import "..\src\lexers/LexAU3.cxx"
Import "..\src\lexers/LexAVE.cxx"
Import "..\src\lexers/LexAVS.cxx"
Import "..\src\lexers/LexBaan.cxx"
Import "..\src\lexers/LexBash.cxx"
Import "..\src\lexers/LexBasic.cxx"
Import "..\src\lexers/LexBullant.cxx"
Import "..\src\lexers/LexCaml.cxx"
Import "..\src\lexers/LexCLW.cxx"
Import "..\src\lexers/LexCmake.cxx"
Import "..\src\lexers/LexCOBOL.cxx"
Import "..\src\lexers/LexCoffeeScript.cxx"
Import "..\src\lexers/LexConf.cxx"
Import "..\src\lexers/LexCPP.cxx"
Import "..\src\lexers/LexCrontab.cxx"
Import "..\src\lexers/LexCsound.cxx"
Import "..\src\lexers/LexCSS.cxx"
Import "..\src\lexers/LexD.cxx"
Import "..\src\lexers/LexECL.cxx"
Import "..\src\lexers/LexEiffel.cxx"
Import "..\src\lexers/LexErlang.cxx"
Import "..\src\lexers/LexEScript.cxx"
Import "..\src\lexers/LexFlagship.cxx"
Import "..\src\lexers/LexForth.cxx"
Import "..\src\lexers/LexFortran.cxx"
Import "..\src\lexers/LexGAP.cxx"
Import "..\src\lexers/LexGui4Cli.cxx"
Import "..\src\lexers/LexHaskell.cxx"
Import "..\src\lexers/LexHTML.cxx"
Import "..\src\lexers/LexInno.cxx"
Import "..\src\lexers/LexKix.cxx"
Import "..\src\lexers/LexLisp.cxx"
Import "..\src\lexers/LexLout.cxx"
Import "..\src\lexers/LexLua.cxx"
Import "..\src\lexers/LexMagik.cxx"
Import "..\src\lexers/LexMarkdown.cxx"
Import "..\src\lexers/LexMatlab.cxx"
Import "..\src\lexers/LexMetapost.cxx"
Import "..\src\lexers/LexMMIXAL.cxx"
Import "..\src\lexers/LexModula.cxx"
Import "..\src\lexers/LexMPT.cxx"
Import "..\src\lexers/LexMSSQL.cxx"
Import "..\src\lexers/LexMySQL.cxx"
Import "..\src\lexers/LexNimrod.cxx"
Import "..\src\lexers/LexNsis.cxx"
Import "..\src\lexers/LexOpal.cxx"
Import "..\src\lexers/LexOScript.cxx"
Import "..\src\lexers/LexOthers.cxx"
Import "..\src\lexers/LexPascal.cxx"
Import "..\src\lexers/LexPB.cxx"
Import "..\src\lexers/LexPerl.cxx"
Import "..\src\lexers/LexPLM.cxx"
Import "..\src\lexers/LexPOV.cxx"
Import "..\src\lexers/LexPowerPro.cxx"
Import "..\src\lexers/LexPowerShell.cxx"
Import "..\src\lexers/LexProgress.cxx"
Import "..\src\lexers/LexPS.cxx"
Import "..\src\lexers/LexPython.cxx"
Import "..\src\lexers/LexR.cxx"
Import "..\src\lexers/LexRebol.cxx"
Import "..\src\lexers/LexRuby.cxx"
Import "..\src\lexers/LexScriptol.cxx"
Import "..\src\lexers/LexSmalltalk.cxx"
Import "..\src\lexers/LexSML.cxx"
Import "..\src\lexers/LexSorcus.cxx"
Import "..\src\lexers/LexSpecman.cxx"
Import "..\src\lexers/LexSpice.cxx"
Import "..\src\lexers/LexSQL.cxx"
Import "..\src\lexers/LexTACL.cxx"
Import "..\src\lexers/LexTADS3.cxx"
Import "..\src\lexers/LexTAL.cxx"
Import "..\src\lexers/LexTCL.cxx"
Import "..\src\lexers/LexTCMD.cxx"
Import "..\src\lexers/LexTeX.cxx"
Import "..\src\lexers/LexTxt2tags.cxx"
Import "..\src\lexers/LexVB.cxx"
Import "..\src\lexers/LexVerilog.cxx"
Import "..\src\lexers/LexVHDL.cxx"
Import "..\src\lexers/LexVisualProlog.cxx"
Import "..\src\lexers/LexYAML.cxx"

Import "..\helper\scintilla_structs.bmx"
Import "..\helper\scintilla_consts.bmx"


Extern
'int Scintilla_RegisterClasses(void *hInstance) {
Function Scintilla_RegisterClasses:Int(hInstance:Int)

End Extern

Scintilla_RegisterClasses(0)

'#end region 


Type ScintillaWinDriver Extends ScintillaAbstractDriver
	Field parent:TGadget
	Field _scintillactrl:TScintillaGadget
	
	Method Init(panel:TGadget)
		parent = panel
		_scintillactrl = TScintillaGadget.CreateScintilla(,,, , parent, Self)
		SetGadgetLayout(_scintillactrl, 1, 1, 1, 1)
	End Method
	
	Method IsNullDriver:TGadget()
		Return Null
	End Method
	
	Method SendEditor:Int(MSG:Int, wParam:Int = 0, lParam:Int = 0)
		Return SendMessageW(_scintillactrl._hwnd, MSG, wParam, lParam)
	End Method
	
	Method DoPrint()
		_scintillactrl.DoPrint()
	End Method
End Type

Function CreateDriver:ScintillaAbstractDriver()
	Return New ScintillaWinDriver
End Function


Function scnwinfilter:Int(event:TEvent, context:Object)
	Select event.id
		Case EVENT_KEYDOWN
			If event.mods = MODIFIER_CONTROL Then
				Return 0
			End If
		Case EVENT_KEYCHAR
			If event.mods = MODIFIER_CONTROL Then
				Return 0
			End If
	End Select
	
	Return 1
End Function


Type TScintillaGadget Extends TWindowsGadget
	
	Field _oldSelPos% , _oldSelLen% = 0
	Field readonly:Byte = False
	Field numbers:Byte = False
	Field _sdriver:ScintillaWinDriver
	Global _pagemargin:Float = 0.5
	
	Function CreateScintilla:TScintillaGadget(X:Int = 0, Y:Int = 0, w:Int = -1, h:Int = -1, group:TGadget = Null, Driver:ScintillaWinDriver)
		If w = -1 Then w = ClientWidth(group)-x
		If h = -1 Then h = ClientHeight(group) - Y
		Local temp:TScintillaGadget = New TScintillaGadget.Initialize(X, Y, w, h, group, 0)
		temp._sdriver = Driver
		Return temp
	End Function
	
	Method Create:TWindowsGadget(group:TGadget, style:Int, Text$="")
	End Method
	
	Method Initialize:TScintillaGadget(X:Int, Y:Int, w:Int, h:Int, group:TGadget, Style:Int)
		
		Local	xstyle:Int,wstyle:Int, hwnd:Int, parent:Int
		
		Self.style = style
		xstyle=WS_EX_CLIENTEDGE
		wstyle=WS_CHILD|WS_VSCROLL|WS_CLIPSIBLINGS
		wstyle:|ES_MULTILINE|ES_NOOLEDRAGDROP|ES_NOHIDESEL|ES_LEFT
		wstyle=WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS
		parent=group.query(QUERY_HWND_CLIENT)
		hwnd=CreateWindowExW(xstyle,"Scintilla","",wstyle,0,0,0,0,parent,0,GetModuleHandleW(Null),Null)		
		
		_SetParent group	
		Register GADGET_TEXTAREA, hwnd
		SetShape(x,y,w,h)
		SetShow(True)
		Sensitize()
		
		Self.SetFilter(scnwinfilter, Null)
	
		Return Self	
	EndMethod
		
	Method OnNotify:Int(wp:Int, lp:Int)
		If _sdriver <> Null Then
			_sdriver.OnNotify(wp, lp)
		End If
	EndMethod
	
	Method WndProc:Int(hwnd:Int,msg:Int,wp:Int,lp:Int)
	
	Local nmhdr:Int Ptr
		Local event:TEvent
		
		nmhdr = Int Ptr(wp)
		
		'If wp = 0 Then Return 0
		
		Select MSG
			Case WM_RBUTTONDOWN
				If GetSelectionLength(TEXTAREA_CHARS)=0 MSG=WM_LBUTTONDOWN
			Case WM_RBUTTONUP
				Local mx:Int=lp & $ffff
				Local my:Int = lp Shr 16
				.PostGuiEvent EVENT_GADGETMENU, TGadget(_sdriver._parent), 0, 0, mx, my
			Case WM_KEYDOWN
				Local k:Int=wp'nmhdr[4]
				'Event Filter
				event = CreateEvent(EVENT_KEYDOWN, TGadget(_sdriver._parent), K, KeyMods())
				If eventfilter <> Null
					If eventfilter(event, context) = 0 Return False
				EndIf
			Case WM_CHAR
				If readonly Return 1
				event = CreateEvent(EVENT_KEYCHAR, TGadget(_sdriver._parent), wp, KeyMods())
				If eventfilter<>Null
					If eventfilter(event , context) = 0 Return False
				EndIf
			Case WM_SETTINGCHANGE
				DebugLog ("** SETTING Changed")
				_sdriver.SendEditor(WM_SETTINGCHANGE, wp, lp) ;
				'SendOutput(WM_SETTINGCHANGE, wParam, lParam);
			Case WM_SYSCOLORCHANGE
				DebugLog("** Color Changed\n");
				_sdriver.SendEditor(WM_SYSCOLORCHANGE, wp, lp) ;
				'SendOutput(WM_SYSCOLORCHANGE, wParam, lParam);
			Case WM_PALETTECHANGED
				DebugLog("** Palette Changed\n")
				_sdriver.SendEditor(WM_PALETTECHANGED, wp, lp) ;
					'//SendOutput(WM_PALETTECHANGED, wParam, lParam);
			Case WM_QUERYNEWPALETTE
				DebugLog("** Query palette\n");
				_sdriver.SendEditor(WM_QUERYNEWPALETTE, wp, lp) ;
				'//SendOutput(WM_QUERYNEWPALETTE, wParam, lParam);
		End Select
			
		Return Super.WndProc(hwnd, MSG, wp, lp)

	EndMethod
	
	Method KeyMods:Int()
		Local mods:Int
		If GetKeyState(VK_SHIFT)&$8000 mods:|MODIFIER_SHIFT
		If GetKeyState(VK_CONTROL)&$8000 mods:|MODIFIER_CONTROL
		If GetKeyState(VK_MENU)&$8000 mods:|MODIFIER_OPTION
		If GetKeyState(VK_LWIN)&$8000 Or GetKeyState(VK_RWIN)&$8000 mods:|MODIFIER_SYSTEM
		Return mods
	End Method

	
	Method Class:Int()
		Return GADGET_TEXTAREA
	End Method

	Method Free()
		Super.Free()
	EndMethod
	
	Method Activate:Int(cmd:Int)
		Select cmd
			Case ACTIVATE_CUT	
			'	_scintilla.SendEditor(SCI_CUT)
			Case ACTIVATE_COPY	
			'	_scintilla.SendEditor(SCI_COPY)
			Case ACTIVATE_PASTE
			'	DoPaste	
			Case ACTIVATE_PRINT
			'	DoPrint
			Case ACTIVATE_FOCUS
			'	SetFocus _hwnd
			Default
				Return Super.Activate(cmd)
		End Select
	EndMethod
	
	Method DoPrint:Int()
		Local tmpTextSelLen:Int = _sdriver.SendEditor(SCI_GETSELECTIONEND) - _sdriver.SendEditor(SCI_GETSELECTIONSTART)
		Local tmpPrintDialog:PRINTDLGW = New PRINTDLGW
		
		tmpPrintDialog.flags = PD_RETURNDC | PD_HIDEPRINTTOFILE | PD_NOPAGENUMS
		If Not tmpTextSelLen Then tmpPrintDialog.flags:|PD_NOSELECTION
		
		tmpPrintDialog.hwndOwner = _hwnd
		
		If Not PrintDlg( Byte Ptr tmpPrintDialog ) Then Return 0
		
		Local hdcPrinter:Int = tmpPrintDialog.hdc	
		
		Local tmpDoc:DOCINFOW = New DOCINFOW
		Local tmpDocTitle:Short Ptr = AppTitle.ToWString()
		tmpDoc.lpszDocName = tmpDocTitle
		
		Local tmpSuccess:Int = (StartDocW( hdcPrinter, Byte Ptr tmpDoc ) > 0)
		
		
		If tmpSuccess Then
			
			Local _cursor:Int = TWindowsGUIDriver._cursor
			
			SetPointer( POINTER_WAIT )
			
			SetMapMode( hdcPrinter, MM_TEXT )
			
			Local wPage:Int = GetDeviceCaps( hdcPrinter, PHYSICALWIDTH )
			Local hPage:Int = GetDeviceCaps( hdcPrinter, PHYSICALHEIGHT )
			Local xPPI:Int = GetDeviceCaps( hdcPrinter, LOGPIXELSX )
			Local yPPI:Int = GetDeviceCaps( hdcPrinter , LOGPIXELSY )
			Local Margin:Rect = New Rect
			Margin.x1 = GetDeviceCaps(hdcPrinter, PHYSICALOFFSETX)
			margin.y1 = GetDeviceCaps(hdcPrinter, PHYSICALOFFSETY)
			margin.x2 = wPage - GetDeviceCaps(hdcPrinter, HORZRES) - margin.x1 ; 	
			margin.y2 = hPage - GetDeviceCaps(hdcPrinter, VERTRES) - margin.y1 ; 	
			
			Print margin.x1 + "; " + margin.y1 + " ;" + margin.x2 + ";" + margin.y2

			Local tmpTextLengthStruct:Int[] = [GTL_DEFAULT, 1200]
			Local tmpTextLength:Int = _sdriver.SendEditor(SCI_GETTEXTLENGTH)
			
			Local tmpTextPrinted:Int, tmpFormatRange:FORMATRANGE = New FORMATRANGE
			
			tmpFormatRange.hdc = hdcPrinter
			tmpFormatRange.hdcTarget = hdcPrinter
			
			tmpFormatRange.rcPageRight = (wPage*1440:Long)/xPPI
			tmpFormatRange.rcPageBottom = (hPage*1440:Long)/yPPI
			
			tmpFormatRange.rcLeft = (1440*_pagemargin);tmpFormatRange.rcTop = (1440*_pagemargin)
			tmpFormatRange.rcRight = tmpFormatRange.rcPageRight - (1440 * _pagemargin)
			tmpFormatRange.rcBottom = tmpFormatRange.rcPageBottom - (1440 * _pagemargin)

			If tmpPrintDialog.flags & PD_SELECTION Then
				tmpTextPrinted = _sdriver.SendEditor(SCI_GETSELECTIONNSTART)
				tmpFormatRange.CHARRANGE_cpMax = tmpTextPrinted+tmpTextSelLen
			Else
				tmpFormatRange.CHARRANGE_cpMax = tmpTextLength
			EndIf
			
			_sdriver.SendEditor(SCI_FORMATRANGE, False, 0)
			
			While tmpSuccess And (tmpTextPrinted < tmpFormatRange.CHARRANGE_cpMax)
				tmpFormatRange.CHARRANGE_cpMin = tmpTextPrinted
				tmpSuccess = (StartPage(hdcPrinter) > 0)
				If Not tmpSuccess Then Exit
				tmpTextPrinted = _sdriver.SendEditor(SCI_FORMATRANGE, True, Int Byte Ptr tmpFormatRange) ;
				tmpSuccess = (EndPage(hdcPrinter) > 0)				
			Wend
			
			If tmpSuccess Then EndDoc( hdcPrinter ) Else AbortDoc( hdcPrinter )
			
			_sdriver.SendEditor(SCI_FORMATRANGE, False, 0)
			
			TWindowsGUIDriver._cursor = _cursor
			SetCursor _cursor
			
		EndIf
		
		GlobalFree( tmpPrintDialog.hDevMode )
		GlobalFree( tmpPrintDialog.hDevNames )
		DeleteDC( hdcPrinter )
		
		MemFree tmpDocTitle			
	EndMethod
	
End Type


